<template>
    <div id="container">
        <div id="editor-box">
            <canvas id="THREE-canvas"></canvas>
        </div>
        <div class="panel">
            <button @click="handleSave">获取保存数据</button>
            <h1>外形自定义</h1>
            <h2>屋顶类型选取</h2>
            <div class="proof-type">
                <button @click="handleChangeRoofType('tip')">尖顶</button>
                <button @click="handleChangeRoofType('round')">圆顶</button>
                <button @click="handleChangeRoofType('flat')">平顶</button>
            </div>
            <button @click="building.enableAdjustProof">启用天窗选取</button>
            <button @click="building.disableAdjustProof">禁用天窗选取</button>
            <h2>尺寸编辑</h2>
            <div>基础比例尺</div>
            <input type="number" v-model="scale.baseScale">
            <div>X缩放</div>
            <input type="number" v-model="scale.resetScaleX">
            <div>Y缩放</div>
            <input type="number" v-model="scale.resetScaleY">
            <div>Z缩放</div>
            <input type="number" v-model="scale.resetScaleZ">
            <button @click="changeScale">渲染</button>
            <!-- <h2>遮阳帘调节</h2> -->
            <!-- <el-slider v-model="sunshadeOpenPercent" :format-tooltip="formatTooltip" @input="handleChangeSunShade" /> -->
            <h2>材质编辑</h2>
            <button @click="changeSideTexture('glass-set')">玻璃材质-前后左右</button>
            <button @click="changeSideTexture('glass')">玻璃材质-左右</button>
            <h1>种植区域自定义</h1>
            <h2>作物架</h2>
            <button @click="handleCreateCropRack('default')">新增【品字-作物架】</button>
            <button @click="handleCreateCropRack('flat')">新增【平面-作物架】</button>
            <button @click="plantAreaManager.closeEdit">退出编辑</button>
            <div class="crop">
                <ul class="crop-list">
                    <li v-for="(item) in cropRacksList">
                        🧹作物架{{ item.id }}
                        <button @click="handleOpenCropRack(item)">编辑</button>
                        <button @click="handleDeleteCropRack(item)">删除</button>
                        <button @click="handleChangeCropRack('crop', item)">添加【农作物】</button>
                        <button @click="handleChangeCropRack('crop-delete', item)">删除【农作物】</button>
                    </li>
                </ul>
            </div>
            <h2>作物块</h2>
            <button @click="handleEditPlantArea">编辑【作物块形状】</button>
            <button @click="plantAreaManager.removeAllCropPlots">清除所有【作物块】</button>
            <div class="crop">
                <ul class="crop-list">
                    <li v-for="(item) in cropPlotsList" :id="item.getId().toString()">
                        🌾 作物块{{ item.getId() }}
                        <button @click="handleOpenCropPlot(item)">编辑</button>
                        <button @click="handleDeleteCropPlot(item)">删除</button>
                    </li>
                </ul>
                <ul class="crop-editor">
                    作物块编辑器
                    <button @click="handleEditCropPlot('mud')">修改【土壤】</button>
                    <button @click="handleEditCropPlot('crop')">修改【农作物】</button>
                </ul>
            </div>
            <h1>设备控制</h1>
            <h2>设备编辑</h2>
            <h3>添加【墙面吸附设备】</h3>
            <div class="side-device">
                <button @click="handleEditDevice('sideDevice', 'left')">【左侧面】</button>
                <button @click="handleEditDevice('sideDevice', 'right')">【右侧面】</button>
                <button @click="handleEditDevice('sideDevice', 'front')">【前面】</button>
                <button @click="handleEditDevice('sideDevice', 'back')">【后面】</button>
            </div>
            <h3>添加【内部设备】</h3>
            <button style="margin-top: 10px;" @click="handleEditDevice('insideDevice')">添加【内部】设备</button>
            <button @click="handleEditDevice('finish')">退出【编辑】</button>
            <button @click="handleEditDevice('clear')">清空【设备】</button>
            <div class="deivce">
                <ul class="device-list">
                    <li v-for="(item, index) in deviceList">
                        ⚙ 设备{{ index + 1 }}
                        <button @click="handleOpenDevice(item)">编辑</button>
                        <button @click="handleDeleteDevice(item.id)">删除</button>
                    </li>
                </ul>
            </div>
            <h3>控制【湿帘】</h3>
            <button @click="handleControlWetCurtain('open')">启用湿帘</button>
            <button @click="handleControlWetCurtain('close')">禁用湿帘</button>
            <button @click="handleControlWetCurtain('wet')">开启加湿状态</button>
            <button @click="handleControlWetCurtain('default')">关闭加湿状态</button>
        </div>
    </div>
</template>

<script setup lang='ts'>
import { onMounted, onBeforeUnmount, Ref, ref } from 'vue';
import * as THREE from 'three';
import Light from '@/utils/Editor/Light';
import { enableAxesHelper } from '@/utils/Editor/Helper';
import CSSManager from '@/utils/Editor/Manager/CSSManager';
// 新封装的编辑器组件
import GreenHouse from '@/editor/GreenHouse/GreenHouse';
import PlantAreaManager from '@/editor/PlantAreaManager';
import Controls from '@/editor/Controls';
import DeviceManager from '@/editor/DeviceManager';
import { createCameraTween } from '@/editor/tools/useTween';
import * as TWEEN from '@tweenjs/tween.js'
import { getDeviceDatas, getCropRackDatas, getCropPlotDatas } from '@/editor/tools/mock';


let camera, renderer;
let scene: Editor.BaseModelOption['scene'];
let cssManager: CSSManager

let building: GreenHouse;

function animate() {
    requestAnimationFrame(animate);
    // tween动画更新
    TWEEN.update();
    renderer.render(scene, camera);
    cssManager && cssManager.render()
    controls && controls.update();
}

function loadBuilding() {
    building = new GreenHouse({
        controls,
        proofType: 'round',
        scene,
        scale: {
            base: 0.5,
            x: 1.5,
            y: 1.5,
            z: 2
        },
        plugins: [
            {
                name: 'DeviceManager',
                option: {
                    camera,
                    preloadDeviceRawDatas: getDeviceDatas()
                }
            },
            {
                name: 'PlantAreaManager',
                option: {
                    camera,
                    /** 如果需要预加载rack，在这里传递数据 */
                    preloadCropRackRawDatas: getCropRackDatas(),
                    /** 如果需要预加载plot，在这里传递数据 */
                    preloadCropPlotRawDatas: getCropPlotDatas()
                }
            }]

    })
    building.on(GreenHouse.EVENT_BASEMODEL_SCALE_CHANGED, (_scale: Editor.BaseModelScale) => {
        scale.value.baseScale = _scale.base
        scale.value.resetScaleX = _scale.x
        scale.value.resetScaleY = _scale.y
        scale.value.resetScaleZ = _scale.z
    })
    building.on(GreenHouse.EVENT_BASEMODEL_LOADED, (model: THREE.Object3D) => {
        // model.position.set(100, 0, -200)
        // 测试用
        building.changeAroundTexture([
            { sideTypeKey: 'left', url: '3D/building/new/gangjia.png', opacity: 0.5 },
            { sideTypeKey: 'right', url: '3D/building/new/gangjia.png', opacity: 0.5 },
            { sideTypeKey: 'front', url: '3D/building/glass_frontBack.png', opacity: 0.5 },
            { sideTypeKey: 'back', url: '3D/building/glass_frontBack.png', opacity: 0.5 },
            // { sideTypeKey: 'leftWetCurtain', url: '3D/building/new/wetcurtain.jpg' },
        ])
    })
    building.on(GreenHouse.EVENT_BASEMODEL_PLUGINS_LOADED, (plugins: Editor.Plugins) => {
        plantAreaManager = building.getPluginByName('PlantAreaManager')
        if (plantAreaManager) {
            plantAreaManager.on(PlantAreaManager.EVENT_CROP_STAFF_UPDATE, ({ cropPlots, cropRacks }) => {
                cropPlots && (cropPlotsList.value = cropPlots)
                cropRacks && (cropRacksList.value = cropRacks)
            })
        }

        deviceManager = building.getPluginByName('DeviceManager')
        if (deviceManager) {
            deviceManager.on(DeviceManager.EVENT_DEVICE_MANAGER_UPDATE, ({ devices }) => {
                deviceList.value = devices
            })
        }
    })
}

function handleChangeRoofType(type) {
    building && building.changeProofType(type)
}


const sunshadeOpenPercent = ref(0)
const formatTooltip = (val) => {
    return `${val}%`
}
function handleChangeSunShade() {
    building && building.adjustSunShade(sunshadeOpenPercent.value / 100)
}

function changeScale() {
    building && building.changeScale({
        base: scale.value.baseScale,
        x: scale.value.resetScaleX,
        y: scale.value.resetScaleY,
        z: scale.value.resetScaleZ
    })
}

function changeSideTexture(type: string) {
    if (building) {
        switch (type) {
            case 'glass': {
                building.changeAroundTexture([
                    { sideTypeKey: 'left', url: '3D/building/new/gangjia.png', opacity: 0.5 },
                    { sideTypeKey: 'right', url: '3D/building/new/gangjia.png', opacity: 0.5 },
                ])
            } break;
            case 'glass-set': {
                building.changeAroundTexture([
                    { sideTypeKey: 'left', url: '3D/building/new/gangjia.png', opacity: 0.5 },
                    { sideTypeKey: 'right', url: '3D/building/new/gangjia.png', opacity: 0.5 },
                    { sideTypeKey: 'front', url: '3D/building/glass_frontBack.png', opacity: 0.5 },
                    { sideTypeKey: 'back', url: '3D/building/glass_frontBack.png', opacity: 0.5 },
                ])
            } break;
        }
    }
}

let plantAreaManager: PlantAreaManager;
function handleEditPlantArea() {
    if (!plantAreaManager) return;
    plantAreaManager.enableShapeEditor()
}

const cropPlotsList: Ref<Array<Editor.CropPlot>> = ref([])
let selectedCropPlotId: string | number = null
const handleOpenCropPlot = (item: Editor.CropPlot) => {
    // 这里存储ID是安全的做法, 如果将选中的plot删除，再编辑会导致错误
    selectedCropPlotId = item.getId()
    // TWEEN飞入
    const box = new THREE.Box3().setFromObject(item.model)
    const center = box.getCenter(new THREE.Vector3());
    const endPos = center.clone().addScalar(100)
    endPos.y += 100
    const endTarget = center.clone().addScalar(50)
    createCameraTween({ camera, controls: controls.orbitControls, endPos, endTarget, duration: 500 })
}
const handleDeleteCropPlot = (item: Editor.CropPlot) => {
    plantAreaManager.removeCropPlotById(item.getId())
}

function handleEditCropPlot(type: string) {
    const cropPlot = plantAreaManager.getCropPlotById(selectedCropPlotId)
    if (cropPlot) {
        switch (type) {
            case 'mud': {
                /** FIXME:效果有问题 */
                cropPlot.changeMud({ url: '3D/mud/mud1.png' })
            } break;
            case 'crop': {
                cropPlot.changeCrop({ url: '3D/carrot.fbx', scale: 1 })
            } break;
        }
    }
}

/** 种植架相关 */
const cropRacksList: Ref<Array<Editor.CropRack>> = ref([])
const handleCreateCropRack = (type: string) => {
    switch (type) {
        case 'default': {
            plantAreaManager.createCropRack({
                url: '3D/rack/rack.fbx',
                scale: {
                    base: 0.8,
                },
            })
        } break;
        case 'flat': {
            plantAreaManager.createCropRack({
                url: '3D/rack/rack_flat.fbx',
                scale: {
                    base: 0.8,
                },
            })
        } break;
    }

}
const handleOpenCropRack = (item: Editor.CropRack) => {
    plantAreaManager.openEdit(item)
}
const handleDeleteCropRack = (item: Editor.CropRack) => {
    plantAreaManager.removeCropRackById(item.getId())
}

const handleChangeCropRack = (type: string, item: Editor.CropRack) => {
    switch (type) {
        case 'crop': {
            item.changeCrop({
                url: '3D/carrot.fbx',
                scale: 1,
            })
        } break;
        case 'crop-delete': {
            item.removeAllCrops()
        } break;
    }
}

let deviceManager: DeviceManager = null

let controls: Controls = null

const deviceList: Ref<Array<Editor.Device>> = ref([])
const handleEditDevice = (type: string, sideType?: Editor.AroundSideMeshKeys) => {
    if (!deviceManager) return;
    switch (type) {
        case 'sideDevice':
            deviceManager.createDevice({
                type,
                url: '3D/device/condition.fbx',
                sideType,
                scale: {
                    base: 1.2,
                },
                autoLoad: true,
            })
            break;
        case 'insideDevice':
            deviceManager.createDevice({
                type,
                url: '3D/device/waterValve.fbx',
                scale: {
                    base: 0.1,
                },
                autoLoad: true,
            })
            break;
        case 'finish':
            deviceManager.closeEdit()
            break;
        case 'clear': {
            deviceManager.removeAllDevices()
        } break;
        default:
            break;
    }
}
const handleOpenDevice = (item: Editor.Device) => {
    if (!deviceManager) return;
    deviceManager.openEdit(item)
}
const handleDeleteDevice = (id: string | number) => {
    if (!deviceManager) return;
    deviceManager.removeDeviceById(id)
}

const handleControlWetCurtain = (type: 'open' | 'wet' | 'default' | 'close') => {
    if (!building) return;
    switch (type) {
        case 'open':
            building.setWetCurtainState(true);
            break;
        case 'wet':
            building.changeAroundTexture([
                { sideTypeKey: 'leftWetCurtain', url: '3D/building/new/wetcurtain.jpg', opacity: 0.8 },
            ])
            break;
        case 'default':
            building.changeAroundTexture([
                { sideTypeKey: 'leftWetCurtain', url: '3D/building/new/wetcurtain_default.jpg' },
            ])
            break;
        case 'close':
            building.setWetCurtainState(false);
            break;
    }
}

const handleSave = () => {
    if (!building) return;
    console.log(building.getSaveData())
}

/**
 * @type {Light}
 */
let light;

// 重构init函数，接收初始模式参数
function init() {
    const box = document.getElementById('THREE-canvas');
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, box.clientWidth / box.clientHeight, 0.1, 5000);
    camera.position.set(500 + 200, 1000, 200);
    // camera.position.set(100, 100, 100);
    renderer = new THREE.WebGLRenderer({ antialias: true, canvas: box });
    renderer.setSize(box.clientWidth, box.clientHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setClearColor(0x000000);

    enableAxesHelper(scene)

    light = new Light({ scene })
    // 添加网格辅助线
    const grid = new THREE.GridHelper(2000, 50, 0xffffff, 0xffffff);
    grid.material.opacity = 0.2;
    grid.material.transparent = true;
    scene.add(grid);

    // 创建控制器
    controls = new Controls({
        camera,
        scene,
        renderer,
        boxId: 'editor-box'
    })

    // 创建CSS管理器
    cssManager = new CSSManager({ camera, scene, renderer, containerId: 'editor-box' })

    loadBuilding();

    animate();

}

const scale = ref({
    baseScale: 0.5,
    resetScaleX: 2,
    resetScaleY: 2,
    resetScaleZ: 2,
})

onMounted(() => {
    init();
});

onBeforeUnmount(() => {
    if (renderer) renderer.dispose();
    building && building.destroy()

});
</script>


<style lang="scss" scoped>
#container {
    width: 100%;
    height: 100%;
    display: flex;
    $panelWidth: 20%;

    button {
        margin-top: 5px;
    }

    #editor-box {
        width: calc(100% - #{$panelWidth});
        height: 100%;
        position: relative;

        #THREE-canvas {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 1;
        }
    }

    .panel {
        overflow-y: scroll;
        display: flex;
        flex-direction: column;
        width: $panelWidth;
        height: 100%;
        background-color: #fff;
        padding: 10px;

        .proof-type {
            display: flex;
            width: 100%;
        }

        input {
            width: 60%;
            margin-bottom: 5px;
        }

        .crop {
            width: 100%;
            display: flex;
            margin-top: 10px;

            .crop-list {
                width: 100%;
            }

            .crop-editor {
                width: 50%;
                background-color: whitesmoke;
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;

            }
        }

        .device {
            width: 100%;
            display: flex;
            margin-top: 10px;

            .device-list {
                width: 50%;
            }
        }
    }
}
</style>